home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / comm / tcp / BBGopher10.lha / bbgopher / src / bbgopher.c next >
C/C++ Source or Header  |  1995-04-19  |  21KB  |  992 lines

  1. /*
  2.  * $VER: bbgopher.c 1.0 (20.4.95)
  3.  * Copyright (c) 1995 Jason M. Weber (Amiga port)
  4.  * Copyright (c) 1993 Mark Morley (original BBGopher for UNIX)
  5.  * Freely distributable
  6.  */
  7.  
  8. #include <sys/types.h>
  9. #include <sys/socket.h>
  10. #include <netinet/in.h>
  11. #include <netdb.h>
  12. #include <fcntl.h>
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17.  
  18. #include "bbgopher.h"
  19.  
  20. int
  21. ValidNumber(number, string)
  22.  int number;
  23.  char *string;
  24. {
  25.  int n1, n2, r;
  26.  
  27.  while (*string) {
  28.   r = 0;
  29.   while (*string == ' ' || *string == '\t' || *string == ',')
  30.    string++;
  31.   n1 = 0;
  32.   n2 = 0;
  33.   if (*string >= '0' && *string <= '9') {
  34.    n1 = atoi(string);
  35.    while (*string >= '0' && *string <= '9')
  36.     string++;
  37.   }
  38.   if (*string == '-') {
  39.    r = 1;
  40.    string++;
  41.    n2 = atoi(string);
  42.    while (*string >= '0' && *string <= '9')
  43.     string++;
  44.   }
  45.   if (r) {
  46.    if (number >= n1 && number <= n2)
  47.     return 1;
  48.   }
  49.   else if (number == n1)
  50.    return 1;
  51.  }
  52.  return 0;
  53. }
  54.  
  55. int
  56. CheckUser(type)
  57.  char type;
  58. {
  59.  FILE *fp;
  60.  char line[80];
  61.  char *uid;
  62.  int i;
  63.  
  64.  for (i = 0; KnownTypes[i].type; i++)
  65.   if (KnownTypes[i].type == type)
  66.    break;
  67.  if (KnownTypes[i].type == 0)
  68.   return 0;
  69.  fp = fopen(KnownTypes[i].acf, "r");
  70.  if (!fp)
  71.   return 1;
  72.  uid = (char *)getlogin();
  73.  for (fgets(line, 80, fp); !feof(fp); fgets(line, 80, fp)) {
  74.   line[strlen(line) - 1] = 0;
  75.   if (strcmp(line, uid) == 0) {
  76.    fclose(fp);
  77.    return 1;
  78.   }
  79.  }
  80.  fclose(fp);
  81.  return 0;
  82. }
  83.  
  84. int
  85. SupportedType(type)
  86.  char type;
  87. {
  88.  int i;
  89.  
  90.  for (i = 0; KnownTypes[i].type; i++)
  91.   if (KnownTypes[i].type == type)
  92.    return KnownTypes[i].supported;
  93.  return 0;
  94. }
  95.  
  96. int
  97. newEntry(ent, type, display, selector, hostname, port)
  98.  GO4ENTRY *ent;
  99.  char type;
  100.  char *display;
  101.  char *selector;
  102.  char *hostname;
  103.  short port;
  104. {
  105.  if (display && (ent->display = (char *)malloc(strlen(display) + 1)) == 0)
  106.   return 0;
  107.  if (selector && (ent->selector = (char *)malloc(strlen(selector) + 1)) == 0) {
  108.   free(ent->display);
  109.   return 0;
  110.  }
  111.  if (hostname && (ent->hostname = (char *)malloc(strlen(hostname) + 1)) == 0) {
  112.   free(ent->selector);
  113.   free(ent->display);
  114.   return 0;
  115.  }
  116.  ent->type = type;
  117.  if (display)
  118.   strcpy(ent->display, display);
  119.  else
  120.   ent->display = 0;
  121.  if (selector)
  122.   strcpy(ent->selector, selector);
  123.  else
  124.   ent->selector = 0;
  125.  if (hostname)
  126.   strcpy(ent->hostname, hostname);
  127.  else
  128.   ent->hostname = 0;
  129.  ent->port = port;
  130.  return 1;
  131. }
  132.  
  133. int
  134. delEntry(ent)
  135.  GO4ENTRY *ent;
  136. {
  137.  if (ent->hostname)
  138.   free(ent->hostname);
  139.  if (ent->selector)
  140.   free(ent->selector);
  141.  if (ent->display)
  142.   free(ent->display);
  143.  return 1;
  144. }
  145.  
  146. char *
  147. TypeLookup(type)
  148.  char type;
  149. {
  150.  int i;
  151.  static char buf[10];
  152.  
  153.  for (i = 0; KnownTypes[i].type; i++)
  154.   if (KnownTypes[i].type == type)
  155.    return KnownTypes[i].display;
  156.  sprintf(buf, " %c ", type);
  157.  return buf;
  158. }
  159.  
  160. int
  161. DisplayLookup(display)
  162.  char *display;
  163. {
  164.  int i;
  165.  
  166.  for (i = 0; i < KnownTypes[i].type; i++)
  167.   if (!strcmp(KnownTypes[i].display, display))
  168.    return i;
  169.  return -1;
  170. }
  171.  
  172. int
  173. Connect(selector, hostname, port)
  174.  char *selector;
  175.  char *hostname;
  176.  short port;
  177. {
  178.  if (port == 0)
  179.   port = DefPort;
  180.  if (ValidNumber(port, BadPorts)) {
  181.   printf("Sorry, but access to that service is not allowed.\n\n");
  182.   return G_CONNECT;
  183.  }
  184.  if (hostname == 0)
  185.   hostname = DefHost;
  186.  if ((host = gethostbyname(hostname)) == 0)
  187.   return G_HOST;
  188.  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  189.   return G_SOCKET;
  190.  bzero(&sain, sizeof(sain));
  191.  sain.sin_family = AF_INET;
  192.  sain.sin_port = htons(port);
  193.  bcopy(host->h_addr, &sain.sin_addr, host->h_length);
  194.  if (connect(sock, (struct sockaddr*)&sain, sizeof(sain)) < 0)
  195.   return G_CONNECT;
  196.  if (selector)
  197.   write(sock, selector, strlen(selector));
  198.  write(sock, "\r\n", 2);
  199.  sd = fdopen(sock, "r");
  200.  return G_OK;
  201. }
  202.  
  203. void
  204. Disconnect(void)
  205. {
  206.  close(sock);
  207. }
  208.  
  209. int
  210. Page(file)
  211.  char *file;
  212. {
  213.  FILE *fp;
  214.  char line[256];
  215.  int n = 0;
  216.  
  217.  fp = fopen(file, "r");
  218.  if (!fp)
  219.   return 0;
  220.  if (ClearScreen)
  221.   printf("\033[2J\033[H");
  222.  else
  223.   putchar('\n');
  224.  for (fgets(line, 256, fp); !feof(fp); fgets(line, 256, fp)) {
  225.   printf(line);
  226.   if (++n == 22) {
  227.    printf("[MORE...]");
  228.    *line = 0;
  229.    fflush(stdin);
  230.    fgets(line, 2, stdin);
  231.    fflush(stdin);
  232.    n = 0;
  233.    if (*line == 'q' || *line == 'Q')
  234.     break;
  235.   }
  236.  }
  237.  fclose(fp);
  238.  return 1;
  239. }
  240.  
  241. int
  242. GetData(file, binary)
  243.  char *file;
  244.  int binary;
  245. {
  246.  FILE *fp;
  247.  int l = 0;
  248.  int t = 0;
  249.  char line[256];
  250.  char ch;
  251.  
  252.  fp = fopen(file, "w");
  253.  if (!fp)
  254.   return G_CREATE;
  255.  if (Twirly)
  256.   putchar(' ');
  257.  if (binary)
  258.   for (ch = getc(sd); !feof(sd); ch = getc(sd)) {
  259.    putc(ch, fp);
  260.    if (Twirly && ++l == 1024) {
  261.     l = 0;
  262.     putchar('\b');
  263.     putchar(TwirlyChars[t]);
  264.     t++;
  265.     if (t == NUMTWIRLYCHARS)
  266.      t = 0;
  267.     fflush(stdout);
  268.    }
  269.   }
  270.  else
  271.   for (fgets(line, 255, sd); !feof(sd); fgets(line, 255, sd)) {
  272.    l = strlen(line) - 1;
  273.    if (line[l] == '\n' && line[l - 1] == '\r') {
  274.     line[l - 1] = '\n';
  275.     line[l] = 0;
  276.    }
  277.    if (*line == '.' && (line[1] == '\r' || line[1] == '\n'))
  278.     break;
  279.    fprintf(fp, line);
  280.    if (Twirly) {
  281.     putchar('\b');
  282.     putchar(TwirlyChars[t]);
  283.     t++;
  284.     if (t == NUMTWIRLYCHARS)
  285.      t = 0;
  286.     fflush(stdout);
  287.    }
  288.   }
  289.  if (Twirly)
  290.   printf("\b \b");
  291.  fclose(fp);
  292.  return G_OK;
  293. }
  294.  
  295. int
  296. GetFile(selector, hostname, port, type, binary)
  297.  char *selector;
  298.  char *hostname;
  299.  short port;
  300.  char *type;
  301.  int binary;
  302. {
  303.  char line[81];
  304.  int rc;
  305.  
  306.  printf("Local name for %s file? ", type);
  307.  fflush(stdin);
  308.  fgets(line, 80, stdin);
  309.  fflush(stdin);
  310.  printf("\n");
  311.  line[strlen(line) - 1] = 0;
  312.  if (*line == 0)
  313.   return G_OK;
  314.  if ((rc = Connect(selector, hostname, port)) != G_OK)
  315.   return rc;
  316.  printf("Retrieving file...");
  317.  fflush(stdout);
  318.  rc = GetData(line, binary);
  319.  printf("\n\n");
  320.  Disconnect();
  321.  return rc;
  322. }
  323.  
  324. int
  325. MailFile(filename)
  326.  char *filename;
  327. {
  328.  FILE *fi;
  329.  FILE *fo;
  330.  char *tmp;
  331.  char to[81];
  332.  char sub[81];
  333.  char ch;
  334.  
  335.  printf("To [%s]: ", getlogin());
  336.  fflush(stdin);
  337.  fgets(to, 80, stdin);
  338.  to[strlen(to) - 1] = 0;
  339.  if (*to == 0)
  340.   strcpy(to, (char *)getlogin());
  341.  printf("Subject: ");
  342.  fflush(stdin);
  343.  fgets(sub, 80, stdin);
  344.  fflush(stdin);
  345.  printf("\n");
  346.  sub[strlen(sub) - 1] = 0;
  347.  if (*sub == 0)
  348.   strcpy(sub, "No Subject Specified");
  349.  printf("Mailing file...\n\n");
  350.  tmp = tmpnam("T:bbgo");
  351.  if ((fo = fopen(tmp, "w")) == NULL) {
  352.   free(tmp);
  353.   return G_CREATE;
  354.  }
  355.  fi = fopen(filename, "r");
  356.  fprintf(fo, "To: %s\n", to);
  357.  fprintf(fo, "Subject: %s\n", sub);
  358.  fprintf(fo, "\n");
  359.  for (ch = fgetc(fi); !feof(fi); ch = fgetc(fi))
  360.   fputc(ch, fo);
  361.  fclose(fi);
  362.  fclose(fo);
  363.  sprintf(sub, "%s %s < %s", Mailer, to, tmp);
  364.  system(sub);
  365.  unlink(tmp);
  366.  free(tmp);
  367.  return G_OK;
  368. }
  369.  
  370. int
  371. SaveFile(filename)
  372.  char *filename;
  373. {
  374.  FILE *fi;
  375.  FILE *fo;
  376.  char line[81];
  377.  char temp[81];
  378.  char *l;
  379.  char ch;
  380.  
  381.  printf("Local name for TXT file? ");
  382.  fflush(stdin);
  383.  fgets(line, 80, stdin);
  384.  fflush(stdin);
  385.  printf("\n");
  386.  line[strlen(line) - 1] = 0;
  387.  if (*line == 0)
  388.   return G_OK;
  389.  if (*Directory) {
  390.   l = (char *)rindex(line, '/');
  391.   if (l)
  392.    *l++ = 0;
  393.   else
  394.    l = line;
  395.   *temp = 0;
  396.   if (*Directory == '~') {
  397.    strcpy(temp, (char *)getenv("HOME"));
  398.    strcat(temp, &Directory[1]);
  399.   }
  400.   else
  401.    strcat(temp, Directory);
  402.   if (temp[strlen(temp) - 1] != '/')
  403.    strcat(temp, "/");
  404.   strcat(temp, l);
  405.   l = temp;
  406.  }
  407.  else
  408.   l = line;
  409.  printf("Saving file...\n\n");
  410.  fflush(stdout);
  411.  if ((fo = fopen(l, "w")) == NULL)
  412.   return G_CREATE;
  413.  fi = fopen(filename, "r");
  414.  for (ch = fgetc(fi); !feof(fi); ch = fgetc(fi))
  415.   fputc(ch, fo);
  416.  fclose(fi);
  417.  fclose(fo);
  418.  return G_OK;
  419. }
  420.  
  421. int
  422. ReadText(selector, hostname, port)
  423.  char *selector;
  424.  char *hostname;
  425.  short port;
  426. {
  427.  char *tmp;
  428.  char line[256];
  429.  int rc;
  430.  
  431.  if ((rc = Connect(selector, hostname, port)) != G_OK)
  432.   return rc;
  433.  printf("Retrieving text...");
  434.  fflush(stdout);
  435.  tmp = tmpnam("T:bbgo");
  436.  if ((rc = GetData(tmp, 0)) != G_OK) {
  437.   free(tmp);
  438.   return rc;
  439.  }
  440.  printf("\n");
  441.  Disconnect();
  442.  if (*Pager == 0 || !strcmp(Pager, "default"))
  443.   Page(tmp);
  444.  else {
  445.   sprintf(line, Pager, tmp);
  446.   if (!strstr(Pager, "%s")) {
  447.    strcat(line, " ");
  448.    strcat(line, tmp);
  449.   }
  450.   system(line);
  451.  }
  452.  printf("\nPress ENTER to continue, M to mail, S to save: ");
  453.  fflush(stdin);
  454.  fgets(line, 5, stdin);
  455.  fflush(stdin);
  456.  printf("\n");
  457.  rc = G_OK;
  458.  if (*line == 'm' || *line == 'M')
  459.   rc = MailFile(tmp);
  460.  else if (*line == 's' || *line == 'S')
  461.   rc = SaveFile(tmp);
  462.  unlink(tmp);
  463.  free(tmp);
  464.  return rc;
  465. }
  466.  
  467. int
  468. DoSearch(selector, hostname, port)
  469.  char *selector;
  470.  char *hostname;
  471.  short port;
  472. {
  473.  char buf[256];
  474.  char line[81];
  475.  int rc;
  476.  
  477.  printf("Please enter your search criteria (you may use 'and' and 'or'):\n");
  478.  fflush(stdin);
  479.  fgets(line, 80, stdin);
  480.  fflush(stdin);
  481.  printf("\n");
  482.  line[strlen(line) - 1] = 0;
  483.  if (*line == 0)
  484.   return G_OK;
  485.  sprintf(buf, "%s\t%s\r\n", selector, line);
  486.  if ((rc = Connect(buf, hostname, port)) != G_OK)
  487.   return rc;
  488.  printf("Searching...\n");
  489.  rc = ReadMenu("Index Search Results", buf, hostname, port, 0, 0);
  490.  Disconnect();
  491.  return rc;
  492. }
  493.  
  494. int
  495. ReadMenu(display, selector, hostname, port, connect, fd)
  496.  char *display;
  497.  char *selector;
  498.  char *hostname;
  499.  short port;
  500.  int connect;
  501.  FILE *fd;
  502. {
  503.  char line[1025];
  504.  char *e;
  505.  GO4ENTRY ent;
  506.  int rc;
  507.  int t;
  508.  
  509.  if (connect)
  510.   if ((rc = Connect(selector, hostname, port)) != G_OK)
  511.    return rc;
  512.  if (StackLen >= MAXSTACKLEN) {
  513.   if (connect)
  514.    Disconnect();
  515.   return G_STACK;
  516.  }
  517.  if (BM) {
  518.   StackLen--;
  519.   delEntry(&Stack[StackLen]);
  520.   StackLen--;
  521.   BM = 0;
  522.  }
  523.  if (!newEntry(&Stack[StackLen], '1', display, selector, hostname, port)) {
  524.   if (connect)
  525.    close(sock);
  526.   return G_MEMORY;
  527.  }
  528.  StackLen++;
  529.  MenuLen = 0;
  530.  t = 0;
  531.  if (Twirly)
  532.   putchar(' ');
  533.  if (fd == NULL)
  534.   fd = sd;
  535.  for (fgets(line, 1024, fd); !feof(fd); fgets(line, 1024, fd)) {
  536.   if (*line == '.' && (line[1] == '\r' || line[1] == '\n'))
  537.    break;
  538.   e = line;
  539.   ent.type = *e++;
  540.   ent.display = e;
  541.   while (*e && *e != '\t') e++;
  542.   if (*e) *e++ = 0;
  543.   ent.selector = e;
  544.   while (*e && *e != '\t') e++;
  545.   if (*e) *e++ = 0;
  546.   ent.hostname = e;
  547.   while (*e && *e != '\t') e++;
  548.   if (*e) *e++ = 0;
  549.   ent.port = atoi(e);
  550.   if (SkipType && !SupportedType(ent.type))
  551.    continue;
  552.   if (SkipACF && !CheckUser(ent.type))
  553.    continue;
  554.   if (!newEntry(&Menu[MenuLen], ent.type, ent.display, ent.selector, ent.hostname, ent.port)) {
  555.    Disconnect();
  556.    return G_MEMORY;
  557.   }
  558.   MenuLen++;
  559.   if (MenuLen == MAXMENULEN)
  560.    break;
  561.   if (Twirly) {
  562.    putchar('\b');
  563.    putchar(TwirlyChars[t]);
  564.    t++;
  565.    if (t == NUMTWIRLYCHARS)
  566.     t = 0;
  567.    fflush(stdout);
  568.   }
  569.  }
  570.  if (Twirly)
  571.   printf("\b \b");
  572.  if (connect)
  573.   Disconnect();
  574.  return G_OK;
  575. }
  576.  
  577. void
  578. SaveBookmark(n)
  579.  int n;
  580. {
  581.  FILE *fp;
  582.  char buf[256];
  583.  
  584.  strcpy(buf, (char *)getenv("HOME"));
  585.  strcat(buf, "/");
  586.  strcat(buf, BookMark);
  587.  if ((fp = fopen(buf, "a")) == 0)
  588.   return;
  589.  fprintf(fp, "%c%s\t%s\t%s\t%d\n", Menu[n].type, Menu[n].display, Menu[n].selector, Menu[n].hostname, Menu[n].port);
  590.  fclose(fp);
  591.  printf("Bookmark saved...\n\n");
  592.  return;
  593. }
  594.  
  595. void
  596. DelBookmark(n)
  597.  int n;
  598. {
  599.  FILE *fp;
  600.  int i;
  601.  char buf[256];
  602.  
  603.  strcpy(buf, (char *)getenv("HOME"));
  604.  strcat(buf, "/");
  605.  strcat(buf, BookMark);
  606.  
  607.  if (n < MenuLen - 1)
  608.   bcopy(&Menu[n + 1], &Menu[n], sizeof(GO4ENTRY) * (MenuLen - n - 1));
  609.  MenuLen--;
  610.  if ((fp = fopen(buf, "w")) == 0)
  611.   return;
  612.  for (i = 0; i < MenuLen; i++)
  613.   fprintf(fp, "%c%s\t%s\t%s\t%d\n", Menu[i].type, Menu[i].display, Menu[i].selector, Menu[i].hostname, Menu[i].port);
  614.  fclose(fp);
  615.  printf("Bookmark deleted...\n\n");
  616.  return;
  617. }
  618.  
  619. int
  620. CompareEntries(ent1, ent2)
  621.  GO4ENTRY *ent1;
  622.  GO4ENTRY *ent2;
  623. {
  624.  return strcmp(ent1->display, ent2->display);
  625. }
  626.  
  627. int
  628. ReadBookmarks(void)
  629. {
  630.  FILE *fp;
  631.  char buf[256];
  632.  
  633.  strcpy(buf, (char *)getenv("HOME"));
  634.  strcat(buf, "/");
  635.  strcat(buf, BookMark);
  636.  if ((fp = fopen(buf, "r")) == 0)
  637.   return 0;
  638.  ReadMenu("* Bookmarks *", 0, 0, 0, 0, fp);
  639.  fclose(fp);
  640.  qsort(Menu, MenuLen, sizeof(GO4ENTRY), CompareEntries);
  641.  return 1;
  642. }
  643.  
  644. int
  645. ProcessMenu(void)
  646. {
  647.  int i, n;
  648.  int top;
  649.  char *s;
  650.  char buf[256];
  651.  
  652.  top = 0;
  653. page:
  654.  if (ClearScreen)
  655.   printf("\033[2J\033[H");
  656.  printf("%s\n%s", Title, Stack[StackLen - 1].display);
  657.  if (Stack[StackLen - 1].hostname)
  658.   printf(" (%s)", Stack[StackLen - 1].hostname);
  659.  printf("\n\n");
  660.  if (MenuLen == 0)
  661.   printf("There are no menu items available.\n");
  662.  else for (i = 0, n = top; i < Lines && n < MenuLen; i++, n++) {
  663.   if (Menu[n].type == 'i')
  664.    printf("%3d %-.75s\n", n + 1, Menu[n].display);
  665.   else
  666.    printf("%3d <%s> %-.69s\n", n + 1, TypeLookup(Menu[n].type), Menu[n].display);
  667.  }
  668.  putchar('\n');
  669. loop:
  670.  do {
  671.   *buf = 0;
  672.   if (MenuLen == 0)
  673.    printf("Help, Quit or Previous: ");
  674.   else
  675.    printf("[1-%d], Help, Quit, %s, List, Previous, Up, or Down: ", MenuLen, BM ? "Delete" : "=, Bookmarks, Save");
  676.   fflush(stdin);
  677.   fgets(buf, 15, stdin);
  678.   fflush(stdin);
  679.   buf[strlen(buf) - 1] = 0;
  680.  } while (*buf == 0 && MenuLen <= Lines);
  681.  printf("\n");
  682.  if (*buf == 'h' || *buf == 'H') {
  683.   if (*Pager == 0 || !strcmp(Pager, "default"))
  684.    Page(HelpFile);
  685.   else {
  686.    sprintf(buf, Pager, HelpFile);
  687.    if (!strcmp(Pager, "%s")) {
  688.     strcat(buf, " ");
  689.     strcat(buf, HelpFile);
  690.    }
  691.    system(buf);
  692.   }
  693.   printf("\nPress ENTER to continue");
  694.   fflush(stdin);
  695.   fgets(buf, 5, stdin);
  696.   fflush(stdin);
  697.   printf("\n");
  698.   goto page;
  699.  }
  700.  if (*buf == 'q' || *buf == 'Q')
  701.   return -2;
  702.  if (!BM && *buf == '=') {
  703.   for (s = buf; *s && *s != ' '; s++);
  704.   n = atoi(s);
  705.   if(n < 0 || n > MenuLen)
  706.    printf("You must specify a valid item number to save as a bookmark (eg: s 1).\n\n");
  707.   else if (n == 0) {
  708.    printf("Type:     %s\n", TypeLookup(Stack[StackLen - 1].type));
  709.    printf("Title:    %s\n", Stack[StackLen - 1].display);
  710.    printf("Host:     %s\n", Stack[StackLen - 1].hostname);
  711.    printf("Port:     %d\n", Stack[StackLen - 1].port);
  712.    printf("Selector: %s\n\n", Stack[StackLen - 1].selector ? Stack[StackLen - 1].selector : "");
  713.   }
  714.   else {
  715.    printf("Type:     %s\n", TypeLookup(Menu[n - 1].type));
  716.    printf("Title:    %s\n", Menu[n - 1].display);
  717.    printf("Host:     %s\n", Menu[n - 1].hostname);
  718.    printf("Port:     %d\n", Menu[n - 1].port);
  719.    printf("Selector: %s\n\n", Menu[n - 1].selector ? Menu[n - 1].selector : "");
  720.   }
  721.   goto loop;
  722.  }
  723.  if (!BM && (*buf == 'b' || *buf == 'B'))
  724.   return -3;
  725.  if (!BM && (*buf == 's' || *buf == 'S')) {
  726.   for (s = buf; *s && *s != ' '; s++);
  727.   n = atoi(s);
  728.   if (n < 1 || n > MenuLen)
  729.    printf("You must specify a valid menu item number to save as a bookmark (eg: s 1).\n\n");
  730.   else
  731.    SaveBookmark(n - 1);
  732.   goto loop;
  733.  }
  734.  if (BM && (*buf == 'd' || *buf == 'D')) {
  735.   for (s = buf; *s && *s != ' '; s++);
  736.   n = atoi(s);
  737.   if (n < 1 || n > MenuLen)
  738.    printf("You must specify a valid item number to delete. (eg: d 1)\n\n");
  739.   else
  740.    DelBookmark(n - 1);
  741.   goto loop;
  742.  }
  743.  if (*buf == 'p' || *buf == 'P')
  744.   return -1;
  745.  if (*buf == 'l' || *buf == 'L')
  746.   goto page;
  747.  if (*buf == 'd' || *buf == 'D' || *buf == 0) {
  748.   top += Lines - 1;
  749.   if (top >= MenuLen - 1)
  750.    top = 0;
  751.   goto page;
  752.  }
  753.  if (*buf == 'u' || *buf == 'U') {
  754.   if (top == 0)
  755.    top = MenuLen - Lines;
  756.   else
  757.    top -= Lines - 1;
  758.   if (top < 0)
  759.    top = 0;
  760.   goto page;
  761.  }
  762.  i = atoi(buf);
  763.  if (i < 1 || i > MenuLen) {
  764.   printf("Please enter a command or a number between 1 and %d.\n\n", MenuLen);
  765.   goto loop;
  766.  }
  767.  i--;
  768.  if (Menu[i].type == 'i') {
  769.   printf("That menu item is informational only.\n\n");
  770.   goto loop;
  771.  }
  772.  if (!SupportedType(Menu[i].type)) {
  773.   printf("Sorry, that type of menu item isn't currently supported.\n\n");
  774.   goto loop;
  775.  }
  776.  if (!CheckUser(Menu[i].type)) {
  777.   printf("Sorry, but you don't have access to that item.\n\n");
  778.   goto loop;
  779.  }
  780.  return i;
  781. }
  782.  
  783. int
  784. Setup(void)
  785. {
  786.  FILE *fp;
  787.  char line[91];
  788.  char *var;
  789.  char *val;
  790.  char *e;
  791.  int i;
  792.  
  793.  strcpy(Title, DEFAULTTITLE);
  794.  strcpy(DefHost, DEFAULTHOST);
  795.  DefPort = DEFAULTPORT;
  796.  *BadPorts = 0;
  797.  strcpy(Pager, DEFAULTPAGER);
  798.  strcpy(Telnet, DEFAULTTELNET);
  799.  strcpy(TN3270, DEFAULTTN3270);
  800.  strcpy(Directory, DEFAULTDIR);
  801.  Lines = DEFAULTLINES;
  802.  Twirly = 1;
  803.  ClearScreen = 0;
  804.  SkipACF = 0;
  805.  SkipType = 1;
  806.  fp = fopen(CONFIGPATH, "r");
  807.  if (!fp)
  808.   return 0;
  809.  for (fgets(line, 90, fp); !feof(fp); fgets(line, 90, fp)) {
  810.   e = (char *)rindex(line, '#');
  811.   if (e)
  812.    *e-- = 0;
  813.   else {
  814.    e = line + strlen(line) - 1;
  815.    *e-- = 0;
  816.   }
  817.   for (var = line; *var == ' ' || *var == '\t'; var++);
  818.   for (val = var; *val && *val != ' ' && *val != '\t'; val++);
  819.   if (*val) *val++ = 0;
  820.   while (*val == ' ' || *val == '\t')
  821.    val++;
  822.   if (*val == '\"') val++;
  823.   while (*e == ' ' || *e == '\t')
  824.    *e-- = 0;
  825.   if (*e == '\"') *e = 0;
  826.   if (*var == 0 || *var == '#')
  827.    continue;
  828.   if (!strcmp(var, "TITLE"))
  829.    strcpy(Title, val);
  830.   else if (!strcmp(var, "SERVER"))
  831.    strcpy(DefHost, val);
  832.   else if (!strcmp(var, "PORT"))
  833.    DefPort = atoi(val);
  834.   else if (!strcmp(var, "BADPORTS"))
  835.    strcpy(BadPorts, val);
  836.   else if (!strcmp(var, "HELPFILE"))
  837.    strcpy(HelpFile, val);
  838.   else if (!strcmp(var, "PAGER"))
  839.    strcpy(Pager, val);
  840.   else if (!strcmp(var, "WORKDIR"))
  841.    strcpy(Directory, val);
  842.   else if (!strcmp(var, "MAILER"))
  843.    strcpy(Mailer, val);
  844.   else if (!strcmp(var, "BOOKMARK"))
  845.    strcpy(BookMark, val);
  846.   else if (!strcmp(var, "TELNET"))
  847.    strcpy(Telnet, val);
  848.   else if (!strcmp(var, "TN3270"))
  849.    strcpy(TN3270, val);
  850.   else if (!strcmp(var, "LINES"))
  851.    Lines = atoi(val);
  852.   else if (!strcmp(var, "TWIRLY"))
  853.    Twirly = (*val == 'y' || *val == 'Y' || *val == '1');
  854.   else if (!strcmp(var, "CLEAR"))
  855.    ClearScreen = (*val == 'y' || *val == 'Y' || *val == '1');
  856.   else if (!strcmp(var, "SKIPACF"))
  857.    SkipACF = (*val == 'y' || *val == 'Y' || *val == '1');
  858.   else if (!strcmp(var, "SKIPTYPE"))
  859.    SkipType = (*val == 'y' || *val == 'Y' || *val == '1');
  860.   else if (!strncmp(var, "ACF", 3) && (i = DisplayLookup(&var[3])) != -1)
  861.    strcpy(KnownTypes[i].acf, val);
  862.   else
  863.    printf("Warning: unrecognised option in configuration file (%s)\n", var);
  864.  }
  865.  return 1;
  866. }
  867.  
  868. int
  869. main(argc, argv)
  870.  int argc;
  871.  char **argv;
  872. {
  873.  int ok;
  874.  int rc;
  875.  int rc2;
  876.  char buf[10];
  877.  
  878.  printf("\033[2J\033[H");
  879.  printf("\nBBGopher 1.6 - Written by Mark Morley (September '93)\n");
  880.  printf("BBGopher/amiga 1.0 - Ported by Jason M. Weber (20.4.95)\n");
  881.  if (!Setup())
  882.   printf("Warning: no configuration file found, using defaults.\n");
  883.  putchar('\n');
  884.  StackLen = 0;
  885.  if (argc > 1) {
  886.   strcpy(DefHost, argv[1]);
  887.   if (argc > 2)
  888.    DefPort = atoi(argv[2]);
  889.  }
  890.  rc = ReadMenu("Default Gopher Server", 0, DefHost, DefPort, 1, 0);
  891.  if (rc != G_OK) {
  892.   printf("Sorry, but I was unable to connect to %s on port %d\n", DefHost, DefPort);
  893.   exit(1);
  894.  }
  895.  BM = 0;
  896.  ok = 1;
  897.  while (ok) {
  898.   rc = ProcessMenu();
  899.   switch (rc) {
  900.    case -1:
  901.     BM = 0;
  902.     if (StackLen > 1) {
  903.      StackLen--;
  904.      delEntry(&Stack[StackLen]);
  905.      StackLen--;
  906.      ReadMenu(Stack[StackLen].display, Stack[StackLen].selector, Stack[StackLen].hostname, Stack[StackLen].port, 1, 0);
  907.     }
  908.     break;
  909.    case -2:
  910.     ok = 0;
  911.     break;
  912.    case -3:
  913.     if (BM == 0) {
  914.      ReadBookmarks();
  915.      BM = 1;
  916.     }
  917.     break;
  918.    default:
  919.     if (BM && StackLen > 1) {
  920.      StackLen--;
  921.      delEntry(&Stack[StackLen]);
  922.     }
  923.     BM = 0;
  924.     switch (Menu[rc].type) {
  925.      case '0':
  926.       rc2 = ReadText(Menu[rc].selector, Menu[rc].hostname, Menu[rc].port);
  927.       break;
  928.      case '1':
  929.       rc2 = ReadMenu(Menu[rc].display, Menu[rc].selector, Menu[rc].hostname, Menu[rc].port, 1, 0);
  930.       break;
  931.      case '4':
  932.       rc2 = GetFile(Menu[rc].selector, Menu[rc].hostname, Menu[rc].port, "Mac HQX", 1);
  933.       break;
  934.      case '5':
  935.       rc2 = GetFile(Menu[rc].selector, Menu[rc].hostname, Menu[rc].port, "DOS binary", 1);
  936.       break;
  937.      case '6':
  938.       rc2 = GetFile(Menu[rc].selector, Menu[rc].hostname, Menu[rc].port, "UU encoded", 0);
  939.       break;
  940.      case '7':
  941.       rc2 = DoSearch(Menu[rc].selector, Menu[rc].hostname, Menu[rc].port);
  942.       break;
  943.      case '8':
  944.       if (*Menu[rc].selector)
  945.        printf("Try logging in as '%s'\n\n", Menu[rc].selector);
  946.       sprintf(buf, "%s %s %d", Telnet, Menu[rc].hostname, Menu[rc].port ? Menu[rc].port : 23);
  947.       system(buf);
  948.       rc2 = G_OK;
  949.       break;
  950.      case '9':
  951.       rc2 = GetFile(Menu[rc].selector, Menu[rc].hostname, Menu[rc].port, "binary", 1);
  952.       break;
  953.      case 'T':
  954.       sprintf(buf, "%s %s %d", TN3270, Menu[rc].hostname, Menu[rc].port ? Menu[rc].port : 23);
  955.       system(buf);
  956.       rc2 = G_OK;
  957.       break;
  958.     }
  959.     if (rc2 != G_OK) {
  960.      printf("ERROR: ");
  961.      switch (rc2) {
  962.       case G_HOST:
  963.        printf("Couldn't resolve hostname '%s'\n", Menu[rc].hostname);
  964.        break;
  965.       case G_SOCKET:
  966.        printf("Socket error!\n");
  967.        break;
  968.       case G_CONNECT:
  969.        printf("Couldn't connect to %s\n", Menu[rc].hostname);
  970.        break;
  971.       case G_CREATE:
  972.        printf("Couldn't create local file.\n");
  973.        break;
  974.       default:
  975.        printf("Code = %d\n", rc2);
  976.        break;
  977.      }
  978.      putchar('\n');
  979.     }
  980.     break;
  981.   }
  982.  }
  983.  while (MenuLen) {
  984.   MenuLen--;
  985.   delEntry(&Menu[MenuLen]);
  986.  }
  987.  while (StackLen) {
  988.   StackLen--;
  989.   delEntry(&Stack[StackLen]);
  990.  }
  991. }
  992.